package com.fhs.easycloud.proxy;

import com.alibaba.fastjson.JSONObject;
import com.fhs.easycloud.anno.CloudApi;
import lombok.Data;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.web.client.RestTemplate;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * 代理类
 */
@Data
public class RemoteClientProxy implements MethodInterceptor, Serializable  {

    private static final long serialVersionUID = 1L;

    private RestTemplate restTemplate;

    private final Enhancer enhancer = new Enhancer();

    /**
     * 获取代理对象
     *
     * @param clazz
     * @return
     */
    public Object getProxy(Class clazz) {
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);
        return enhancer.create();
    }

    /**
     * 这一段代码是重点，为了获取参数名，我此处使用的cglib代理。
     */
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        Object result = exec(method, objects);
        return result;
    }

    private Object exec(Method method, Object[] objects) {
        CloudApi cloudApi =  method.getDeclaringClass().getAnnotation(CloudApi.class);
        if(cloudApi==null){
            throw new RuntimeException(method.getDeclaringClass() + "目标类没有加CloudApi");
        }
        Map<String,Object> paramMap = new HashMap<>();
        for (int i = 0; i < objects.length; i++) {
            paramMap.put(i + "",objects[i]);
        }
        //获取基础url
        Class<?> clazz = method.getDeclaringClass();
        //执行远程调用
        String respJson = restTemplate.postForObject("http://" + cloudApi.serviceName()
                + "/easyCloud/proxy/" + clazz.getName() + "/" + method.getName(),paramMap,String.class);
        if(void.class.equals(method.getReturnType())){
            return null;
        }
        if(respJson == null){
            return respJson;
        }
        return JSONObject.parseObject(respJson,method.getGenericReturnType());
    }



}
